package com.soxing.webrain.brush.common.util;

import com.google.gson.*;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.*;

public class ObjectUtil {

    private static Random random;

    static {
        try {
            random = SecureRandom.getInstanceStrong();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception {
//		Application obj = initClassInfo(Application.class);
//
//		List<AppIconVo> iconList = new ArrayList<AppIconVo>();
//		AppIconVo o1 = initClassInfo(AppIconVo.class);
//		AppIconVo o2 = initClassInfo(AppIconVo.class);
//		AppIconVo o3 = initClassInfo(AppIconVo.class);
//		iconList.add(o1);
//		iconList.add(o2);
//		iconList.add(o3);
//
//		obj.setIcon(toJson(iconList));
//
//		String json = toJson(obj);
//		Application d = fromJson(json, Application.class);
//		String icon = d.getIcon();
//		System.out.println(icon);
//		iconList = fromArrayJson(icon, AppIconVo.class);
//		System.out.println(toJson(iconList));


		String json = "{\n" +
				"   \"OnSubscriberStatusChanged\" : {\n" +
				"      \"Number\" : \"8004\",\n" +
				"      \"OppNumber\" : \"\",\n" +
				"      \"Status\" : 0\n" +
				"   }\n" +
				"}";
		JsonObject jsonObject = getJsonObject(json);
		String number = jsonObject.get("OnSubscriberStatusChanged").getAsJsonObject().get("Number").getAsString();
		System.out.println(number);
    }

    /***
     * @param json
     * @return com.google.gson.JsonObject
     * @Author durango
     * @CreateTime 2021-05-13 13:16:53
     * @Description: json字符串变为JsonObject对象
     */
    public static JsonObject getJsonObject(String json) {
        return JsonParser.parseString(json).getAsJsonObject();
    }


    /**
     * json字符串转对象
     *
     * @param <T>  目标类型
     * @param json json字符串
     * @param cls  目标类
     * @return
     */
    public static <T> T fromJson(String json, Class<T> cls) {
        if (json == null) {
            return null;
        }
        Gson gson = new Gson();
        return gson.fromJson(json, cls);
    }

    /**
     * json字符串转对象
     *
     * @param <T>     目标类型
     * @param strJson json字符串
     * @param cls     目标类
     * @return
     */
    public static <T> List<T> fromArrayJson(String strJson, Class<T> cls) {
        List<T> rList = new ArrayList<T>();
        if (strJson == null) {
            return null;
        }
        // 创建一个Gson对象
        Gson gson = new Gson();
        // 通过JsonParser对象可以把json格式的字符串解析成一个JsonElement对象
        JsonElement el = JsonParser.parseString(strJson);

        // 把JsonElement对象转换成JsonObject
        JsonObject jsonObj = null;
        if (el.isJsonObject()) {
            jsonObj = el.getAsJsonObject();
            rList.add(gson.fromJson(jsonObj, cls));
            return rList;
        }

        // 把JsonElement对象转换成JsonArray
        JsonArray jsonArray = null;
        if (el.isJsonArray()) {
            jsonArray = el.getAsJsonArray();
            // 遍历JsonArray对象
            Iterator it = jsonArray.iterator();
            while (it.hasNext()) {
                JsonElement e = (JsonElement) it.next();
                // JsonElement转换为JavaBean对象
                rList.add(gson.fromJson(e, cls));
            }
        }
        return rList;
    }

    /**
     * 对象转json字符串
     *
     * @param obj 对象
     * @return json字符串
     */
    public static String toJson(Object obj) {
        Gson gson = new Gson();
        return gson.toJson(obj);
    }

    /**
     * 初始化类数据
     *
     * @param cls
     * @param <T>
     * @return
     * @throws Exception
     */
    public static <T> T initClassInfo(Class<T> cls) {
        T bean = null;
        try {
            bean = cls.newInstance();
            Method[] methods = cls.getDeclaredMethods();
            Field[] fields = cls.getDeclaredFields();

            for (Field field : fields) {
                String fieldSetName = parSetName(field.getName());
                if (!checkSetMet(methods, fieldSetName)) {
                    continue;
                }
                Method fieldSetMet = cls.getMethod(fieldSetName, field.getType());

                fieldSet(bean, fieldSetMet, field);
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("initClassInfo调用异常");
        }
        return bean;
    }

    /**
     * 生成随机数据
     *
     * @param field
     * @return
     */
    private static Object getRandomInfo(Field field) {
        String type = field.getType().getSimpleName();
        try {
            if (type.equals("String")) {
                int length = (int) (Math.random() * 5) + 1;
                String str = "javadeiwiieiwweweweweweweercsdfsdhgjyuiuddgdsgdgseeieiieieoeppepcd9e";
                char[] chr = str.toCharArray();

                StringBuffer buffer = new StringBuffer();
                for (int i = 0; i < length; i++) {
                    buffer.append(chr[random.nextInt(46)]);
                }
                return buffer.toString();
            } else if (type.equals("Date")) {
                return new Date();
            } else if (type.equals("Long") || type.equals("long")) {
                return (long) (Math.random() * 50);
            } else if (type.equals("Integer") || type.equals("int")) {
                return (int) (Math.random() * 50);
            } else if (type.equals("Double") || type.equals("double")) {
                return Math.random() * 100;
            } else if (type.equals("Boolean") || type.equals("boolean")) {
                return true;
            } else if (type.equals("List")) {
                // 获取 list 字段的泛型参数
                ParameterizedType listGenericType = (ParameterizedType) field.getGenericType();
                Type[] listActualTypeArguments = listGenericType.getActualTypeArguments();
                if (listActualTypeArguments == null || listActualTypeArguments.length <= 0) {
                    return null;
                }
                List tmpArr = new ArrayList();
                for (int i = 0; i < 5; i++) {
                    tmpArr.add(initClassInfo(Class.forName(listActualTypeArguments[0].getTypeName())));
                }
                return tmpArr;
            } else {
                return initClassInfo(field.getType());
            }
        } catch (

                Exception e) {
            System.out.println("未找到匹配类型,初始化数据失败" + type);
        }
        return "haha";

    }

    /**
     * 拼接在某属性的 set方法
     *
     * @param fieldName
     * @return String
     */
    private static String parSetName(String fieldName) {
        if (null == fieldName || "".equals(fieldName)) {
            return null;
        }
        int startIndex = 0;
        if (fieldName.charAt(0) == '_'){
            startIndex = 1;
        }
        return "set" + fieldName.substring(startIndex, startIndex + 1).toUpperCase()
                + fieldName.substring(startIndex + 1);
    }

    /**
     * 判断是否存在某属性的 set方法
     *
     * @param methods
     * @param fieldSetMet
     * @return boolean
     */
    private static boolean checkSetMet(Method[] methods, String fieldSetMet) {
        for (Method met : methods) {
            if (fieldSetMet.equals(met.getName())) {
//                System.out.println(fieldSetMet+" true");
                return true;
            }
        }
//        System.out.println(fieldSetMet+" false");
        return false;
    }

    /**
     * 调用某个set方法set数据
     *
     * @param bean
     * @param fieldSetMet
     * @param field
     * @throws Exception
     */
    private static void fieldSet(Object bean, Method fieldSetMet, Field field) throws Exception {
        String fieldType = field.getType().getSimpleName();
        Object value = getRandomInfo(field);
        if ("String".equals(fieldType)) {
            fieldSetMet.invoke(bean, (String) value);
        } else if ("Date".equals(fieldType)) {
            Date temp = (Date) value;
            fieldSetMet.invoke(bean, temp);
        } else if ("Integer".equals(fieldType) || "int".equals(fieldType)) {
            Integer intval = (Integer) value;
            fieldSetMet.invoke(bean, intval);
        } else if ("Long".equalsIgnoreCase(fieldType)) {
            Long temp = (Long) value;
            fieldSetMet.invoke(bean, temp);
        } else if ("Double".equalsIgnoreCase(fieldType)) {
            Double temp = (Double) value;
            fieldSetMet.invoke(bean, temp);
        } else if ("Boolean".equalsIgnoreCase(fieldType)) {
            Boolean temp = (Boolean) value;
            fieldSetMet.invoke(bean, temp);
        } else if ("List".equalsIgnoreCase(fieldType)) {
            List temp = (List) value;
            fieldSetMet.invoke(bean, temp);
        } else {
            fieldSetMet.invoke(bean, value);
            // System.out.println("未找到匹配类型" + fieldType);
        }
    }

}
